<script>
  let state = {
    name: 'moniaca',
    age: 18,
    province: {
      city: {
        name: '北京'
      }
    }
  }
  let activeFn;

  // 依赖收集器 Dep
  class Dep {
    constructor() {
      this.subsDeps = new Set(); // 一个不可重复的数组
    }
    
    depend() {
      if(!activeFn) return; 
      this.subsDeps.add(activeFn);
    }

    notify() {
      // 派发更新依次执行所有依赖的副作用函数
      this.subsDeps.forEach(fn=>fn());
    }

  }

  function autoRun(fn) {
    function updateWrapper() {
      activeFn = updateWrapper;
      fn();  // 该函数的运行期间，activeUpdate一定有值
      activeFn = null;
    }
    updateWrapper();
  }

  // 判断是否为对象
  function isObject(obj) {
    return obj !== null && !Array.isArray(obj) && typeof obj === 'object';
  }

  // 数据劫持 Observer
  function observer(obj) {
    if (!isObject(obj)) {
      return; // 不处理非对象
    }
    Object.keys(obj).forEach(key=>{
      // 每个属性都有一个依赖器
      let dep = new Dep();
      let interValue = obj[key];
      // 递归劫持不能放在get中
      observer(interValue);
      Object.defineProperty(obj,key,{
        get() {
          // console.log(`获取数据${key}属性值为${interValue}`);
          // 收集依赖
          dep.depend();
          return interValue;
        },
        set(val) {
          observer(val);
          interValue = val;
          // 派发更新
          dep.notify();
          console.log(`监听到数据${key}属性被修改为${val}`);
        }
      })
    })
  }

  observer(state);

  autoRun(()=>{
    console.log('依赖的副作用函数执行了',state.age)
  })

  state.age = 20;



</script>